
package com.task.base;

import android.Manifest;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.ListActivity;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.drawable.Drawable;
import android.net.TrafficStats;
import android.os.Bundle;
import android.os.Handler;
import android.text.format.Formatter;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.List;

public class TrafficStatistics extends ListActivity {

    private Context context = null;

    private long totalLoad, totalDelta, totalWork, workDelta;

    private static final int MSG_INIT_OK = 6;

    private PackageManager mPm;

    private ActivityManager am;

    private TextView process;

    private TextView memory;

    private byte[] buf = new byte[512];

    public static final int ITEM_SWITCH = 0;

    public static final int ITEM_KILL = 1;

    public static final int ITEM_UNINSTALL = 2;

    public static final int ITEM_DETAIL = 3;

    public int processSoftBy;



    private HashMap<String, SoftReference<Drawable>> processItemMaps;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.traffic);
        am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
        mPm = getPackageManager();
        processItemMaps = new HashMap<String, SoftReference<Drawable>>();
        context = this;
        initList();
        registerForContextMenu(getListView());
    }

    /**
     * 初始化进程列表
     */
    private void initList() {
        ArrayAdapter<ProcessItem> adapter = new ArrayAdapter<ProcessItem>(this,
                R.layout.traffic_list_item) {

            public android.view.View getView(int position, android.view.View convertView,
                    android.view.ViewGroup parent) {
                View view;
                TextView txt_name, txt_mem, txt_cpu;
                ImageView img_type;

                if (convertView == null) {
                    view = LayoutInflater.from(context).inflate(R.layout.traffic_list_item, parent,
                            false);
                } else {
                    view = convertView;
                }

                if (position >= getCount()) {
                    return view;
                }

                ProcessItem itm = getItem(position);

                img_type = (ImageView) view.findViewById(R.id.itemImage);
                txt_name = (TextView) view.findViewById(R.id.name);
                txt_mem = (TextView) view.findViewById(R.id.infoMem);
                txt_cpu = (TextView) view.findViewById(R.id.infoCpu);
                // closeButton = (ImageButton)
                // view.findViewById(R.id.buttonClose);
                txt_name.setTag(itm);
                String lb = itm.label;
                if (itm.sys) {
                    lb += " *";
                }
                txt_name.setText(lb);
                img_type.setImageDrawable(itm.icon);

                txt_mem.setText(Formatter.formatFileSize(TrafficStatistics.this, itm.tx) + ",");
                txt_cpu.setText(Formatter.formatFileSize(TrafficStatistics.this, itm.rx));
                view.setTag(itm);
                return view;
            }
        };
        getListView().setAdapter(adapter);
    }

    Runnable task = new Runnable() {
        public void run() {
            updateListData();
            handler.sendEmptyMessage(MSG_INIT_OK);
        }
    };

    Handler handler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
                case MSG_INIT_OK:
                    handler.postDelayed(task, 10000);
                    break;

            }
        };
    };

    @Override
    protected void onResume() {
        super.onResume();
        handler.post(task);
    }

    @Override
    protected void onPause() {
        handler.removeCallbacks(task);
        handler.removeMessages(MSG_INIT_OK);
        super.onPause();
    }

    private HashMap<Integer, Long> processCpu = new HashMap<Integer, Long>();

    /**
     * 更新list中数据。
     * 
     * @throws NameNotFoundException
     */
    private void updateListData() {
        List<ApplicationInfo> installedAppList = mPm.getInstalledApplications(0);

        ArrayAdapter<ProcessItem> adapter = (ArrayAdapter<ProcessItem>) getListView().getAdapter();
        processCpu.clear();
        int pid = 0;
        for (int i = 0; i < adapter.getCount(); i++) {
            pid = adapter.getItem(i).pid;
            if (pid > 0) {
                processCpu.put(pid, adapter.getItem(i).cputime);
            }
        }

        adapter.setNotifyOnChange(false);
        adapter.clear();

        RunningAppProcessInfo currentProcess = null;
        ProcessItem currentItem = null;
        boolean isSys = false;
        Drawable icon = null;
        SoftReference<Drawable> reference;
        for (ApplicationInfo appInfo : installedAppList) {
            if (PackageManager.PERMISSION_GRANTED != mPm.checkPermission(
                    Manifest.permission.INTERNET, appInfo.packageName)) {
                continue;
            }
            currentItem = new ProcessItem();
            icon = null;
            reference = processItemMaps.get(appInfo.packageName);

            if (reference != null) {
                icon = reference.get();
            }
            if (icon == null) {
                icon = appInfo.loadIcon(mPm);
                processItemMaps.put(appInfo.packageName, new SoftReference<Drawable>(icon));
            }
            currentItem.icon = icon;
            currentItem.uid = appInfo.uid;
            currentProcess = isRunningProcess(appInfo.packageName);
            // 判断是否系统程序

            isSys = (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) > 0;

            currentItem.sys = isSys;

            if (currentProcess == null) {
                currentItem.mem = "0KB";// 说明当前不是进程
                currentItem.pid = 0;
            } else {
                // 如果是进程
                currentItem.pid = currentProcess.pid;
                if (processCpu.containsKey(currentItem.pid)) {
                    currentItem.lastcputime = processCpu.get(currentItem.pid);

                    currentItem.rx = TrafficStats.getUidRxBytes(currentItem.uid);
                    currentItem.tx = TrafficStats.getUidTxBytes(currentItem.uid);
                }

                Util.readProcessStat(context, buf, currentItem);
            }

            currentItem.label = appInfo.loadLabel(mPm).toString();
            currentItem.packageName = appInfo.packageName;
            currentItem.applicationInfo = appInfo;
            adapter.add(currentItem);

        }
        processCpu.clear();
        adapter.notifyDataSetChanged();
    }

    /**
     * 判断当前的应用程序是否是正在运行的进程.
     * 
     * @param packageName
     * @return
     */
    private RunningAppProcessInfo isRunningProcess(String packageName) {
        List<RunningAppProcessInfo> raps = am.getRunningAppProcesses();
        for (RunningAppProcessInfo process : raps) {
            if (process.processName.equals(packageName)) {
                return process;
            }
        }
        return null;

    }

    private Drawable getIcon(ApplicationInfo applicationInfo) {

        if (applicationInfo != null) {
            Drawable icon = mPm.getApplicationIcon(applicationInfo);
            if (icon == null) {
                try {
                    icon = mPm.getDefaultActivityIcon();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return icon;
        }
        return null;
    }

    private String getProcessName(ApplicationInfo ai) {

        if (ai != null) {
            CharSequence label = mPm.getApplicationLabel(ai);
            if (label != null) {
                return label.toString();
            }
        }
        return "";
    }
}
